home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / datatypes / hsn_dt / source / dispatch.c < prev    next >
C/C++ Source or Header  |  1978-06-29  |  6KB  |  236 lines

  1. /******************************************************************************
  2.  *
  3.  * HSN Datatype, based on the sourcecode found in OS3.1 Native Developer Kit
  4.  *
  5.  * Written by Christian Buchner
  6.  *
  7.  ******************************************************************************
  8.  * dispatch.c
  9.  */
  10.  
  11. #include "classbase.h"
  12.  
  13. /*****************************************************************************/
  14.  
  15. #define DEBUG 1
  16.  
  17. #if DEBUG
  18.  
  19. #define    DB(x)    x
  20.  
  21. #include <stdarg.h>
  22. void __stdargs Error(struct ClassBase *cb,UBYTE *Msg,...)
  23. {
  24.     va_list Arg;
  25.     struct EasyStruct Req={sizeof(struct EasyStruct),0,"HSN debug message",0,"Okay"};
  26.     va_start(Arg,Msg);
  27.     Req.es_TextFormat=Msg;
  28.     EasyRequestArgs(NULL,&Req,0,Arg);
  29.     va_end(Arg);
  30. }
  31.  
  32. #else
  33.  
  34. #define    DB(x)    
  35.  
  36. #endif
  37.  
  38.  
  39.  
  40. /*****************************************************************************/
  41.  
  42. Class *initClass (struct ClassBase * cb)
  43. {
  44.     Class *cl;
  45.     
  46.     if (cl = MakeClass (HSNDTCLASS, SOUNDDTCLASS, NULL, NULL, 0L))
  47.     {
  48.         cl->cl_Dispatcher.h_Entry = (ULONG (*)())Dispatch;
  49.         cl->cl_UserData = (ULONG) cb;
  50.         AddClass (cl);
  51.     }
  52.     
  53.     return (cl);
  54. }
  55.  
  56. /*****************************************************************************/
  57.  
  58. ULONG ASM Dispatch (REG (a0) Class * cl, REG (a2) Object * o, REG (a1) Msg msg)
  59. {
  60.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  61.     ULONG retval = 0L;
  62.     
  63.     switch (msg->MethodID)
  64.     {
  65.     case OM_NEW:
  66.         if (retval = DoSuperMethodA (cl, o, msg))
  67.         {
  68.             if (!(ConvertObjectData (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList)))
  69.             {
  70.                 CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
  71.                 retval = NULL;
  72.             }
  73.         }
  74.         break;
  75.         
  76.      /* Let the superclass handle everything else */
  77.     
  78.     default:
  79.         retval = (ULONG) DoSuperMethodA (cl, o, msg);
  80.         break;
  81.     }
  82.     
  83.     return (retval);
  84. }
  85.  
  86. /*****************************************************************************/
  87.  
  88. struct HSNHeader
  89. {
  90.     UBYTE HSN_ID[8];    /* $00 */
  91.     UBYTE Unknown[12];    /* $08 */
  92.     ULONG Size;            /* $14 */
  93.     UWORD Pitch;        /* $18 */
  94.     UBYTE Unknown2[22];    /* $1a */
  95.                         /* $30 */
  96. };
  97.  
  98. /*****************************************************************************/
  99.  
  100. BOOL ConvertObjectData (struct ClassBase * cb, Class * cl, Object * o, struct TagItem * attrs)
  101. {
  102.     LONG ErrorCode=0;
  103.     struct FileInfoBlock *fib;
  104.     struct VoiceHeader *vhdr;
  105.     STRPTR Title;
  106.     BPTR FH;
  107.     struct HSNHeader *HSNHeader;
  108.     UBYTE HSNDesc[42]="";
  109.     ULONG Memory;
  110.     UBYTE *Sample;
  111.     ULONG Size;
  112.     
  113.     Title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
  114.     
  115.     getdtattrs (cb, o,
  116.         SDTA_VoiceHeader, &vhdr,
  117.         DTA_Handle, &FH,
  118.         TAG_DONE);
  119.     
  120.     if (FH && vhdr)
  121.     {
  122.         /* Allocate a temporary file info block */
  123.         if (!(fib = (struct FileInfoBlock *) AllocMem (sizeof (struct FileInfoBlock), NULL)))
  124.         {
  125.             ErrorCode=ERROR_NO_FREE_STORE;
  126.         }
  127.         else
  128.         {
  129.             /* Get the size of the file */
  130.             if (ExamineFH (FH, fib))
  131.             {
  132.                 Size = fib->fib_Size;
  133.             }
  134.             else
  135.             {
  136.                 Seek (FH, 0, OFFSET_END);
  137.                 Size = Seek (FH, 0, OFFSET_BEGINNING);
  138.             }
  139.             
  140.             /* Free the temporary file info block */
  141.             FreeMem (fib, sizeof (struct FileInfoBlock));
  142.             
  143.             /* Allocate header structure */
  144.             if (!(HSNHeader=AllocVec(sizeof(struct HSNHeader),MEMF_ANY)))
  145.             {
  146.                 ErrorCode=ERROR_NO_FREE_STORE;
  147.             }
  148.             else
  149.             {
  150.                 /* Calculate size from actual file length */
  151.                 /* So even crippled or overlong files can be played completely */
  152.                 Size-=sizeof(struct HSNHeader);
  153.                 
  154.                 /* Read in sample header */
  155.                 if (Read(FH,HSNHeader,sizeof(struct HSNHeader))==sizeof(struct HSNHeader))
  156.                 {
  157.                     /* Versions 1.0 and 1.1 are supported */
  158.                     if (strcmp("HSND1.1",HSNHeader->HSN_ID) && strcmp("HSND1.0",HSNHeader->HSN_ID))
  159.                     {
  160.                         ErrorCode=ERROR_OBJECT_WRONG_TYPE;
  161.                     }
  162.                     else
  163.                     {
  164.                         /* Version 1.1 features a short description */
  165.                         if (HSNHeader->HSN_ID[6]=='1')
  166.                         {
  167.                             Size-=sizeof(HSNDesc);
  168.                             
  169.                             Read(FH,HSNDesc,sizeof(HSNDesc));
  170.                         }
  171.                         
  172.                         /* sound.datatype V40 can replay */
  173.                         /* directly from Fast RAM */
  174.                         
  175.                         Memory = (SuperClassBase->lib_Version>39) ?
  176.                                     MEMF_ANY : MEMF_CHIP;
  177.                         
  178.                         /* Allocate a buffer with the calculated size */
  179.                         if (!(Sample=AllocVec(Size,Memory)))
  180.                         {
  181.                             ErrorCode=ERROR_NO_FREE_STORE;
  182.                         }
  183.                         else
  184.                         {
  185.                             /* This implies that sample data is 8 bit signed */
  186.                             /* Just read the sample into the buffer */
  187.                             if (Read(FH,Sample,Size)==Size)
  188.                             {
  189.                                 /* Fill in the VoiceHeader */
  190.                                 memset(vhdr,0,sizeof(struct VoiceHeader));
  191.                                 vhdr->vh_OneShotHiSamples    = Size;
  192.                                 vhdr->vh_SamplesPerSec        = 10*HSNHeader->Pitch;
  193.                                 vhdr->vh_Octaves            = 1;
  194.                                 vhdr->vh_Compression        = CMP_NONE;
  195.                                 vhdr->vh_Volume                = 64;
  196.                                 
  197.                                 /* Tell the super-class about the attributes */
  198.                                 setdtattrs (cb, o,
  199.                                     DTA_ObjName,        Title,
  200.                                     SDTA_Sample,        Sample,
  201.                                     SDTA_SampleLength,    Size,
  202.                                     SDTA_Period,        (ULONG)(SysBase->ex_EClockFrequency*5)/(ULONG)vhdr->vh_SamplesPerSec,
  203.                                     SDTA_Volume,        64,
  204.                                     SDTA_Cycles,        1,
  205.                                     TAG_DONE);
  206.                             }
  207.                         }
  208.                     }
  209.                 }
  210.                 FreeVec(HSNHeader);
  211.             }
  212.         }
  213.     }
  214.     if (ErrorCode)
  215.     {
  216.         SetIoErr(ErrorCode);
  217.         return(FALSE);
  218.     }
  219.     return(TRUE);
  220. }
  221.  
  222.  
  223. /*****************************************************************************/
  224.  
  225. ULONG setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  226. {
  227.     return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
  228. }
  229.  
  230. /*****************************************************************************/
  231.  
  232. ULONG getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  233. {
  234.     return (GetDTAttrsA (o, (struct TagItem *) & data));
  235. }
  236.